package com.shycloud.mido.member.api.util;

import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import io.swagger.models.auth.In;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Objects;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


/**
 * @author bard.bai
 */
public class QrCodeUtil {

	private static final int IMAGE_WIDTH = 100;
	private static final int IMAGE_HEIGHT = 100;
	private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
	private static final int FRAME_WIDTH = 2;
	private static MultiFormatWriter mutiWriter = new MultiFormatWriter();

	public static byte[] createQrCode(ByteArrayOutputStream bos, String content, int qrCodeSize, String imageFormat)
			throws Exception {

		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		// 矫错级别
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
		// 字符编码
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		// 二维码与图片边距
		hints.put(EncodeHintType.MARGIN, 2);
		QRCodeWriter qrCodeWriter = new QRCodeWriter();

		BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hints);

		MatrixToImageWriter.writeToStream(byteMatrix, imageFormat, bos);

		return bos.toByteArray();
	}

	public static String readQrCode(InputStream inputStream) throws Exception {

		BufferedImage image = ImageIO.read(inputStream);

		LuminanceSource source = new BufferedImageLuminanceSource(image);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		QRCodeReader reader = new QRCodeReader();
		Map<DecodeHintType, Object> hints = new Hashtable<>();

		hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
		//优化精度
		hints.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE);
		Result result = null;
		try {
			result = reader.decode(bitmap, hints);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (Objects.nonNull(result)) {
			return result.getText();
		}
		return StringUtils.EMPTY;
	}


	public static byte[] createQrCodeWithLogo(ByteArrayOutputStream bos, String content, int qrCodeSize, String imageFormat,
			InputStream logoInputStream)
			throws Exception {

		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		// 矫错级别
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
		// 字符编码
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		// 二维码与图片边距
		hints.put(EncodeHintType.MARGIN, 2);
		QRCodeWriter qrCodeWriter = new QRCodeWriter();

		BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hints);

		MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);

		BufferedImage bufferedImage = LogoMatrix(MatrixToImageWriter.toBufferedImage(byteMatrix, matrixToImageConfig),
				logoInputStream);
		//输出带logo图片
		ImageIO.write(bufferedImage, "png", bos);

		return bos.toByteArray();
	}

	/**
	 * 二维码添加logo
	 *
	 * @param matrixImage 源二维码图片
	 * @param logoFile    logo图片
	 * @return 返回带有logo的二维码图片 参考：https://blog.csdn.net/weixin_39494923/article/details/79058799
	 */
	public static BufferedImage LogoMatrix(BufferedImage matrixImage, InputStream logoFile) throws IOException {

		//读取二维码图片，并构建绘图对象
		Graphics2D graphic = matrixImage.createGraphics();
		int matrixWidth = matrixImage.getWidth();
		int matrixHeigh = matrixImage.getHeight();
		//读取Logo图片
		BufferedImage logo = ImageIO.read(logoFile);
		//开始绘制图片
		graphic.drawImage(logo, matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5, matrixHeigh / 5, null);
		BasicStroke stroke = new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
		// 设置笔画对象
		graphic.setStroke(stroke);
		//指定弧度的圆角矩形
		RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5,
				matrixHeigh / 5, 20, 0);

		graphic.setColor(Color.white);
		graphic.draw(round);

		graphic.dispose();
		matrixImage.flush();
		return matrixImage;
	}

	public static void main(String[] args) throws Exception {

		HttpURLConnection connection = (HttpURLConnection) new URL("http://attachment.joymido.com/logo.jpg").openConnection();
		connection.setReadTimeout(5000);
		connection.setConnectTimeout(5000);
		connection.setRequestMethod("GET");
		InputStream inputStream = connection.getInputStream();
		try (ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
			byte[] createQrCode = createQrCodeWithLogo(bos,
					"https://depositlease.joymido.com/#/?orgId=2180",
					1500, "PNG", inputStream);
			ByteArrayInputStream is = new ByteArrayInputStream(createQrCode);
			FileUtils.writeByteArrayToFile(new File("C:/data/qrcode_attend_00a5075ce01b438c8aad9994fd9eed06.png"), createQrCode);
			String readQrCode = readQrCode(is);
			System.out.println(readQrCode);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
	}

}